package com.franklin.ideaplugin.mybatisrunner.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.franklin.ideaplugin.mybatisrunner.xml.MybatisSqlContext;
import com.franklin.ideaplugin.mybatisrunner.xml.node.MybatisNodeHandlers;
import com.franklin.ideaplugin.mybatisrunner.xml.params.MybatisParam;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiAnnotationMemberValue;
import com.intellij.psi.PsiLiteralExpression;
import com.intellij.psi.util.PsiTreeUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.io.StringReader;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author Ye Junhui
 * @since 2024/2/19
 */
public class MybatisSqlUtils {

    /**
     * 解析注解SQL
     *
     * @param psiAnnotation
     * @return
     */
    public static String resolveMybatisSqlScript(PsiAnnotation psiAnnotation) {
        PsiAnnotationMemberValue value = psiAnnotation.findAttributeValue("value");
        if (Objects.isNull(value)) {
            return "";
        }
        List<PsiLiteralExpression> children = PsiTreeUtil.getChildrenOfTypeAsList(value, PsiLiteralExpression.class);
        if (CollectionUtil.isEmpty(children) && value instanceof PsiLiteralExpression){
            children = Lists.newArrayList((PsiLiteralExpression) value);
        }
        String script = children.stream()
                .map(psiLiteralExpression -> {
                    String text = psiLiteralExpression.getText();
                    if (StrUtil.isBlank(text)) {
                        return "";
                    }
                    if (text.startsWith("\"")) {
                        text = text.substring(1);
                    }
                    if (text.endsWith("\"")) {
                        text = text.substring(0, text.length() - 1);
                    }
                    return Symbol.decodeSymbol(text);
                })
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.joining(""));
        if (!script.startsWith("<script>")) {
            script = "<script>\n" + script;
        }
        if (!script.endsWith("</script>")) {
            script = script + "\n</script>";
        }
        return script;
    }

    @Getter
    @RequiredArgsConstructor
    private enum Symbol{

        n("\\n","\n"),
        r("\\r","\r"),
        t("\\t","\t"),
        ;

        /**
         * 错误符号
         */
        private final String errorSymbol;

        /**
         * 正确符号
         */
        private final String correctSymbol;

        /**
         * 解码
         * @param sql
         * @return
         */
        private static String decodeSymbol(String sql) {
            String tempSql = sql;
            for (Symbol symbol : Symbol.values()) {
                tempSql = tempSql.replace(symbol.errorSymbol,symbol.correctSymbol);
            }
            return tempSql;
        }
    }
}
